package pers.cz.chat;

import pers.cz.chat.constants.Commands;
import pers.cz.chat.constants.JefClolorEnum;
import pers.cz.chat.model.dto.InnerCmdMessage;
import pers.cz.chat.utils.JsonUtils;
import pers.cz.chat.utils.LogUtils;

import javax.swing.*;
import javax.swing.text.StyledDocument;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;


/**
 * @program: Jef-Chat
 * @description:
 * @author: Cheng Zhi
 * @create: 2025-01-05 20:46
 **/
public class UiApplication {

    private static PrintWriter printWriter;

    private static Process process;

    private static final String NORMAL_ICON_PATH = "feishu.png"; // 设置为你的正常图标路径

    public static void main(String[] args) throws InterruptedException {

        // 设置系统托盘图标
        if (!SystemTray.isSupported()) {
            LogUtils.print(JefClolorEnum.YELLOW,"System tray is not supported!");
            return;
        }

        // 创建 JFrame
        JFrame frame = new JFrame("Jef-Chat");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        URL iconUrl = UiApplication.class.getClassLoader().getResource(NORMAL_ICON_PATH);
        if (iconUrl == null) {
            throw new IllegalArgumentException("Icon not found at path: " + NORMAL_ICON_PATH);
        }
        ImageIcon icon = new ImageIcon(iconUrl);
        frame.setIconImage(icon.getImage());

        frame.setSize(800, 600);

        // 创建 JTextPane 用于显示 CMD 输出
        JTextPane textPane = new JTextPane();
        textPane.setBackground(Color.BLACK);
        textPane.setForeground(Color.WHITE);
        textPane.setEditable(false);
        textPane.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); // 设置等宽字体
        JScrollPane scrollPane = new JScrollPane(textPane);
        frame.add(scrollPane, BorderLayout.CENTER);

        // 创建输入框
        JTextField textField = new JTextField();
        frame.add(textField, BorderLayout.SOUTH);

        // 创建系统托盘图标
        FlashUtils flashUtils = new FlashUtils(frame);
        flashUtils.createTrayIcon();
        // 启动 CMD 进程
        startCmdProcess(textPane, flashUtils);

        // 处理用户输入
        textField.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String command = textField.getText();
                if (!command.trim().isEmpty()) {

                    if (command.startsWith("-clear")) {
                        textPane.setText("");
                        textField.setText(""); // 清空输入框
                        return;
                    }

                    if (command.startsWith("-exit")) {
                        System.exit(0);
                        return;
                    }

                    // 判断是否是指令
                    if (Commands.contains(command)) {
                        appendColoredText(textPane, command + "\n", Color.CYAN);
                    } else {
                        appendColoredText(textPane, command + "\n", Color.WHITE);
                    }

                    executeCommand(command);
                    textField.setText(""); // 清空输入框
                }
            }
        });

        // 显示窗口
        frame.setVisible(true);

        frame.addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent e) {
                // 关闭子进程
                closeSubProcess();
                System.exit(0);
            }
        });

    }

    /**
     * 追加带颜色的文本到 JTextPane
     */
    private static void appendColoredText(JTextPane textPane, String text, Color color) {
        try {
            StyledDocument doc = textPane.getStyledDocument();
            javax.swing.text.Style style = textPane.addStyle(null, null);
            javax.swing.text.StyleConstants.setForeground(style, color);
            doc.insertString(doc.getLength(), text, style);
            textPane.setCaretPosition(doc.getLength());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void startCmdProcess(JTextPane textPane, FlashUtils flashUtils) {
        try {
            String jarPath = "D:\\vue\\project\\jef-chat\\chat-client\\target\\chat-client-1.0-SNAPSHOT-start.jar";
            //String jarPath = "D:\\Java\\JavaSource\\Jef-Chat\\chat-client\\target\\chat-client-1.0-SNAPSHOT-start.jar";
            if (isJarRun()) {
                InputStream resourceAsStream = UiApplication.class.getClassLoader().getResourceAsStream("BOOT-INF/lib/chat-client-1.0-SNAPSHOT-start.jar");
                File jarFile = new File("client.jar");
	            inputStreamToFile(resourceAsStream, jarFile);
                jarPath = jarFile.getPath();
            }

            java.util.List<String> commands = new ArrayList<String>();
            commands.add("java");
            commands.add("-Dfile.encoding=utf-8");
            if (javaVersionGt8()) {
                commands.add("--add-opens");
                commands.add("java.base/java.nio=ALL-UNNAMED");
            }
            commands.add("-jar");
            commands.add(jarPath);

            ProcessBuilder processBuilder = new ProcessBuilder(commands);
            processBuilder.redirectErrorStream(true);
            process = processBuilder.start();
            printWriter = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"), true);

            new Thread(() -> {
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        try {
                            InnerCmdMessage innerCmdMessage = JsonUtils.fromJson(line, InnerCmdMessage.class);
                            if (innerCmdMessage != null) {
                                line = innerCmdMessage.getMessage();
                                appendColoredText(textPane, line + "\n", innerCmdMessage.getJefColor().toColor());
                                if (line.startsWith("收到")) {
                                    flashUtils.triggerTrayFlashing(); // 每次读取新行时触发托盘闪烁
                                }
                            }
                        } catch (Exception e) {
                            // 不做任何处理
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void executeCommand(String command) {
        if (printWriter != null) {
            printWriter.println(command);
        }
    }

    private static void closeSubProcess() {
        if (process != null) {
            process.destroy();
            try {
                if (!process.waitFor(5, TimeUnit.SECONDS)) {
                    process.destroyForcibly();
                }
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

    public static void inputStreamToFile(InputStream ins, File file) throws IOException {
        if (ins == null) {
            throw new IOException("InputStream is null");
        }
        OutputStream os = new FileOutputStream(file);
        int bytesRead;
        byte[] buffer = new byte[8192];
        while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
    }

    /**
     * 判断是否为jar包运行
     * @return
     */
    private static boolean isJarRun() {
        try {
            Class.forName("com.intellij.rt.execution.application.AppMainV2");
            return false;
        } catch (ClassNotFoundException ignored) {
            return true;
        }
    }

    /**
     * 判断java版本是否大于8
     * @return
     */
    private static boolean javaVersionGt8() {

        String version = System.getProperty("java.version");
        // 对于Java 9及以上的版本，版本字符串格式为 "9" 或者 "9.0.1" 等等
        // 对于Java 8及以下版本，版本字符串格式为 "1.8.0_XXX"
        if (version.startsWith("1.")) {
            int startIdx = version.indexOf('.') + 1;
            int endIdx = version.indexOf('.', startIdx);
            if (endIdx == -1) {
                endIdx = version.indexOf('_', startIdx);
            }
            if (endIdx == -1) {
                endIdx = version.length();
            }
            int majorVersion = Integer.parseInt(version.substring(startIdx, endIdx));
            return majorVersion > 8;
        } else {
            // Java 9 and above
            int dotIdx = version.indexOf('.');
            int majorVersion = dotIdx != -1 ? Integer.parseInt(version.substring(0, dotIdx)) : Integer.parseInt(version);
            return majorVersion > 8;
        }
    }

}
